/**
 * \brief 麦克风获取pcm
 * \note 播放PCM的命令：
 *       ffplay -ar 44100 -ac 2 -f s16le -i test.pcm
 */

#include "module.h"
#include "module_pcmin.h"
#include <string.h> // memcpy
#include <stdio.h>  // printf fflush

#define EPERM 1 /* Operation not permitted */
#define pr_info printf
#define MDATA_LEN (16 * 1024) // 音频44100、双通道、16bit一帧7057字节
volatile int pcmin_module_inputflag = 0;
static unsigned char mdata[MDATA_LEN];
static int mdatalen = 0;
static struct module *target = NULL;

int pcmin_module_register()
{
    pcmin_module_inputflag = 0;
    mdatalen = 0;

    return 0;
}

int pcmin_module_putdata(char *data, int len)
{
    if (!data || len > MDATA_LEN)
        return -EPERM;

    pcmin_module_inputflag = 1; // 上锁
    memcpy(mdata, data, len); // 获取数据
    mdatalen = len;
    pcmin_module_inputflag = 0; // 释放锁

    return 0;
}

static int module_init(void)
{
    if (target)
        target->init();

    return 0;
}

static int module_start(void *param)
{
    start_param_t sparam = {"test.pcm", 4}; // 4 is aac

    if (target)
        target->start(&sparam);

    return 0;
}

static int module_run(void)
{
    if (target)
        target->run();

    if (!mdatalen) // 如果没有数据
        return 0;
    if (!pcmin_module_inputflag) { // 如果空闲
        pcmin_module_inputflag = 1; // 锁住
        if (target)
            target->putdata(mdata, mdatalen, 0);
        mdatalen = 0;
        pcmin_module_inputflag = 0; // 释放锁
    }
    return 0;
}

static int module_stop(void)
{
    if (target)
        target->stop();

    return 0;
}

static int module_exit(void)
{
    if (target)
        target->exit();

    return 0;
}

static int module_settarget(void *mtarget)
{
    target = (struct module *)mtarget;

    return 0;
}

static int module_putdata(void *data, int len, int flag)
{
    return 0;
}

struct module g_module_pcmin = {
    "pcmin", module_init,
    module_start, module_run,
    module_stop, module_exit,
    module_settarget, module_putdata
};

/**
 * ffmpeg -formats 命令查看所有支持的封装格式
 * PCM类：
 * DE f32be           PCM 32-bit floating-point big-endian
 * DE f32le           PCM 32-bit floating-point little-endian
 * DE f64be           PCM 64-bit floating-point big-endian
 * DE f64le           PCM 64-bit floating-point little-endian
 * DE s16be           PCM signed 16-bit big-endian
 * DE s16le           PCM signed 16-bit little-endian
 * DE s24be           PCM signed 24-bit big-endian
 * DE s24le           PCM signed 24-bit little-endian
 * DE s32be           PCM signed 32-bit big-endian
 * DE s32le           PCM signed 32-bit little-endian
 * DE s8              PCM signed 8-bit
 * DE u16be           PCM unsigned 16-bit big-endian
 * DE u16le           PCM unsigned 16-bit little-endian
 * DE u24be           PCM unsigned 24-bit big-endian
 * DE u24le           PCM unsigned 24-bit little-endian
 * DE u32be           PCM unsigned 32-bit big-endian
 * DE u32le           PCM unsigned 32-bit little-endian
 * DE u8              PCM unsigned 8-bit
 */
